2023/12/236207字符
DOM
DOM —— Document Object Model 文档对象模型 (用来操作html、xml功能一类对象的集合)
文档对象模型
将HTML文件解析成一个一个节点对象,再配合JS语法就可以操作文档中的内容了
- HTML中所有的东西都是一个节点,所有的节点都由一个对象构成,包括 document
Document.__proto__ = Node
- Node Document HTMLDocument Element Attr
分类:
- 动态集合: children, childNodes, getElementByTagName
- 静态集合(监听不到节点变化):
querySelectorAll
查看元素节点
document // 代表整个文档
document.getElementById('id'); // 元素 id 在 IE8 以下的浏览器,不区分 id 大小写,而且也返回匹配 name 的属性
document.getElementsByTagName('div')[0]; // 标签名
document.getElementsByName('name')[0]; // name 需注意:只有部分标签name可生效(表单,表单元素,img,iframe)
document.getElementsByClassName('class')[0]; // 类名 -> ie8和ie8以下的ie版本中没有,可以多个class一起
document.querySelector('div>span strong.demo'); // css选择器 在ie7和ie7以下的版本中没有 解决不了实时性问题
document.querySelectorAll('div>span strong.demo'); // css组选择器 在ie7和ie7以下的版本中没有 解决不了实时性问题
节点类型
- 元素节点 - 1
- 属性节点 - 2
- 文本节点 - 3
- 注释节点 - 8
- document - 9
- DocumentFragment - 11
遍历节点树
div.parentNode // 父节点(最顶端的 parentNode 为 #document)
div.childNodes // 子节点们
div.fristChild // 第一个子节点
div.lastChild // 最后一个子节点
div.nextSibling // 后一个兄弟节点
div.previousSibling // 前一个兄弟节点
遍历元素节点树(IE8 及以下不兼容,除 .children)
div.parentElement // 返回当前元素父元素节点
div.children // 只返回当前元素的元素子节点
div.childElementCount // 当前元素节点的子元素 (div.childElementCount === div.children.length)
div.fristElementChild // 第一个元素节点
div.lastElementChild // 最后一个元素节点
div.nextElementSibling // 后一个兄弟元素节点
div.previousElementSibling // 前一个兄弟元素节点
节点的四个属性
- div.nodeName :元素标签名,以大写形式表示(只读)
- div.nodeValue :text 或 comment 节点的文本内容(可读写)
- div.nodeType :该节点的类型(只读)
- div.attributes :elment 节点的属性集合
- div.hasChildNodes() :hasChildNodes() 方法可在某节点用于任何子节点时返回 true,否则返回 false
dom 增 插 删 替换
// <div class="class"><strong></strong><span></span><i></i></div>
// 增
document.createElement('div'); // 增加标签节点
document.createTextNode('div'); // 增加文本节点
document.createComment('div'); // 增加注释节点
document.createDocumentFragment('div'); // 增加文档碎片节点
// 插
div.appendChild(p); // 插入节点(若一个元素插入两个位置会发生剪切作用)
div.insertBefore(p, span); // 在 b 节点前插入节点 a
// 删
span.removeChild(); // 被剪切(谋杀)
span.remove(); // 被删除(自杀)
// 替换
div.replace(em, span); // 新节点 a 替换 b 节点
Element 节点属性
div.innerHTML // 读取 HTML 结构,将 element 节点取出
div.innerHTML = "<span style='width:30px;height:25px;background-color:#f00;color:#fff';>string</span>"; // 覆盖内容
div.innerHTML += 'string'; // 添加内容
div.innerText = 'string'; // 覆盖文本(包括标签) 火狐老版本不兼容
div.textContent = 'string'; // 火狐提出覆盖文本的方法 但(IE)不兼容
Element节点方法
div.setAttribute('id', 'only'); // 添加属性(可设置系统没有的)
div.getAttribute('class'); // 取出属性
div.className = 'class'; // 可读写 class
获取一个元素被点击的次数
// <a herf="#" class="demo" data-log=""></a>
var a = document.getElementsByTagName('a');
a.onclick = function () {
console.log(this.getAttribute('data-log'));
}
封装一个方法,查看第 n 层父元素节点
// <div><strong><span><i></i></span></strong></div>
function reParent (elem, n) {
while(elem && n){
elem = elem.parentElement; // IE 父元素节点选择
n --;
}
return elem;
}
var i = document.getElementsByTagName('i')[0];
console.log(reParent(i, 2)); //--> <strong></strong>
console.log(reParent(i, 6)); //--> null
封装一个 myChildren 功能,解决以前部分浏览器得兼容性问题
// <div><strong><span><i></i></span></strong></div>
Element.prototype.myChildren = function () {
var child = this.childNodes; // 获得 body 子元素集合
var len = child.length;
var arr = [];
for (var i = 0; i < len; i++) {
if (child[i].nodeType == 1) {
arr.push(child[i]);
}
}
return arr;
}
var div = document.getElementsByTagName('div')[0];
console.log(div.myChildren());
封装函数,返回元素 e 的第 n 个兄弟元素节点,n为正返回后面的兄弟元素节点,n为负返回前面的,n为0返回自己
function retSibling (e, n) {
while (e && n) {
if (n > 0) {
if (e.nextElementSibling) {
e = e.nextElementSibling;
} else {
for (e.nextSibling; e && e.nextSibling != 1; e = e.nextSibling);
} // 解决IE兼容性问题
n --;
}else {
if (e.previousElementSibling) {
e = e.previousElementSibling;
} else {
for (e.previousSibling; e && e.previousSibling != 1; e = e.previousSibling);
}
n ++;
}
}
return e;
}
var div = document.getElementsByTagName('div')[1];
console.log(retSibling(div, 2));